package com.css.dzj.dzjap.modules.project.supervision.service.impl;

import com.css.dzj.dzjap.common.util.Constant;
import com.css.dzj.dzjap.common.util.ServiceUtil;
import com.css.dzj.dzjap.common.util.SnowflakeId;
import com.css.dzj.dzjap.modules.project.supervision.entity.QSupervision;
import com.css.dzj.dzjap.modules.project.supervision.entity.Supervision;
import com.css.dzj.dzjap.modules.project.supervision.mapper.SupervisionMapper;
import com.css.dzj.dzjap.modules.project.supervision.service.SupervisionChildService;
import com.css.dzj.dzjap.modules.project.supervision.service.SupervisionService;
import com.css.dzj.dzjap.modules.publick.dao.PublicDao;
import com.css.dzj.dzjap.modules.publick.entity.ApPublicEntity;
import com.css.dzj.dzjap.modules.publick.entity.QApPublicEntity;
import com.css.dzj.dzjap.modules.record.approject.service.ApRecordService;
import com.css.dzj.dzjap.modules.record.community.service.CommunityRecordService;
import com.css.dzj.dzjap.modules.todolist.entity.ApTodoEntity;
import com.css.dzj.dzjap.modules.todolist.entity.QApTodoEntity;
import com.css.dzj.dzjap.modules.todolist.mapper.ApTodoMapper;
import com.querydsl.core.QueryResults;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;

/**
 * 监管工作Service
 *
 * @author liyuan
 */
@Service
public class SupervisionServiceImpl implements SupervisionService {
    @Autowired
    private SupervisionMapper supervisionMapper;
    /**
     * 公开公告Dao
     */
    @Autowired
    private PublicDao publicDao;
    /**
     * 代办已办
     */
    @Autowired
    private ApTodoMapper apTodoMapper;
    @Autowired
    private JPAQueryFactory jpaQueryFactory;
    @Autowired
    private HttpServletRequest request;
    /**
     * 多表关联查询注入各个表的service
     */
    @Autowired
    private SupervisionChildService supervisionChildService;

    @Override
    public QueryResults<Supervision> getPage(String proName, String projectType, String suType, String checkStatus,
                                             String reportStatus, String suCreateUser, String suTime, String projectAddress,
                                             String orgLevel, Pageable pageable) {
        QSupervision q = QSupervision.supervision;
        Predicate predicate = q.isNotNull().or(q.isNull());
        /**
         * 1> 项目地址包含中国时,查找已上报的
         * 2> 项目地址不包含中国时,查找项目地址
         */
        if (!StringUtils.isEmpty(projectAddress) && projectAddress.contains("中国")) {
            // 此时若传入上报状态参数,搜查语句不拼接上报状态参数，直接用固定的数值：1
            predicate = ExpressionUtils.and(predicate, q.reportStatus.eq("1"));
        }
        if (!StringUtils.isEmpty(projectAddress) && !projectAddress.contains("中国")) {
            // 省级：山东省地震局   地市级：山东省-济南市地震局
            predicate = ExpressionUtils.and(predicate, q.projectAddress.like("%" + projectAddress + "%"));
            /**
             ** 北京市-北京市-朝阳区
             ** 若是省级用户新增，只展示在省级用户的界面 地市级用户不会展示
             ** 地市级用户新增未提交只展示在地市级用户界面，不会展示在上级界面，只有提交后展示在省级用户界面
             **/
            // 用户组织等级 2：地市级
            if ("2".equals(orgLevel)) {
                // 地市级只能查询地市级的
                predicate = ExpressionUtils.and(predicate, q.orgLevel.eq("2"));
            }
            // 用户组织等级1：省级
            if ("1".equals(orgLevel)) {
                // 省级查询省级所有信息和地市级已提交所有的
                predicate = ExpressionUtils.and(predicate, q.orgLevel.eq("2").and(q.checkStatus.ne("0")));
                predicate = ExpressionUtils.or(predicate, q.orgLevel.eq("1"));
            }
            // 此时若传入上报状态参数,搜查语句拼接上报状态参数，用传入的值：reportStatus
            predicate = (StringUtils.isEmpty(reportStatus)) ? predicate : ExpressionUtils.and(predicate, q.reportStatus.eq(reportStatus));
        }
        // 测试阶段不传项目地址，可以查找上报状态
        if (StringUtils.isEmpty(projectAddress)) {
            predicate = (StringUtils.isEmpty(reportStatus)) ? predicate : ExpressionUtils.and(predicate, q.reportStatus.eq(reportStatus));
        }

        // 拼接条件
        predicate = (proName == null || proName.isEmpty()) ? predicate : ExpressionUtils.and(predicate, q.projectName.like("%" + proName + "%"));
        predicate = (projectType == null || projectType.isEmpty()) ? predicate : ExpressionUtils.and(predicate, q.projectType.like("%" + projectType + "%"));
        predicate = (suType == null || suType.isEmpty()) ? predicate : ExpressionUtils.and(predicate, q.suType.like("%" + suType + "%"));
        predicate = (checkStatus == null || checkStatus.isEmpty()) ? predicate : ExpressionUtils.and(predicate, q.checkStatus.like("%" + checkStatus + "%"));
        predicate = (suCreateUser == null || suCreateUser.isEmpty()) ? predicate : ExpressionUtils.and(predicate, q.suCreateUser.like("%" + suCreateUser + "%"));
        predicate = (suTime == null || suTime.isEmpty()) ? predicate : ExpressionUtils.and(predicate, q.suTime.like("%" + suTime + "%"));
        // 搜索未删除的
        predicate = ExpressionUtils.and(predicate, q.delFlag.eq(Constant.NO_DELETE));
        // 返回结果
        return jpaQueryFactory
                .selectFrom(q)
                .where(predicate)
                .orderBy(
                        // 根据创建日期，降序排序
                        q.createTime.desc()
                )
                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .fetchResults();
    }

    @Override
    public Supervision queryById(String id) {
        if (StringUtils.isEmpty(id)) {
            throw new RuntimeException("ID不能为空");
        }
        Supervision supervision = supervisionMapper.findById(id).get();
        return supervision;
    }


    /**
     * 已办待办任务默认设置接口
     * 说明：新增、暂存==> 待办，审核未过==>已办
     *
     * @param supervision
     */
    private void setApTodo(Supervision supervision) {
        ApTodoEntity todoEntity = new ApTodoEntity();
        // 标题后缀根据审核状态
        String suffix = "";
        if ("0".equals(supervision.getCheckStatus())) {
            // 暂存后不进入待办了
            suffix = "待提交";
        }
        if ("1".equals(supervision.getCheckStatus())) {
            suffix = "待审定";
        }
        todoEntity.setTitle(supervision.getProjectName() + suffix);
        todoEntity.setCreateTime(new Date());
        todoEntity.setLocation(supervision.getProjectAddress().split("-")[0]);
        todoEntity.setDelFlag(Constant.NO_DELETE);
        // 新增方法任务默认1：待办
        todoEntity.setStatus(Constant.STATUSDB);
        todoEntity.setCreatePerson(supervision.getSuCreateUser());
        todoEntity.setTypeFlag(Constant.TYPRFLAGSS);
        // url 待改
        todoEntity.setUrl("../todolist/supervision.html");
        todoEntity.setLinkId(supervision.getSuId());
        todoEntity.setStation("项目审核员");
        apTodoMapper.save(todoEntity);
    }

    /**
     * supervisions批量新增
     * apTodo也要批量新增待办任务
     *
     * @param supervisions
     */
    @Override
    public void save(List<Supervision> supervisions) {
        if (StringUtils.isEmpty(supervisions)) {
            throw new RuntimeException("备案表集合为空");
        }
        // 遍历，设置默认值
        for (Supervision supervision : supervisions) {
            // 前端生成ID，一般不用设置此ID
            if (StringUtils.isEmpty(supervision.getSuId()))
                supervision.setSuId(SnowflakeId.getId());
            supervision.setDelFlag(Constant.NO_DELETE);
            supervision.setCreateTime(new Date());
        }
        // 新增
        supervisionMapper.saveAll(supervisions);
    }

    @Override
    public void save(Supervision supervision) {
        if (StringUtils.isEmpty(supervision)) {
            throw new RuntimeException("备案表为空");
        }
        // 必须用UUID生成ID 设置上报状态为0：未上报
        if (StringUtils.isEmpty(supervision.getSuId())) {
            // 前端生成ID，一般不用设置此ID
            supervision.setSuId(SnowflakeId.getId());
        }
        supervision.setReportStatus(Constant.REPORT_NO);
        supervision.setDelFlag(Constant.NO_DELETE);
        supervision.setCreateUser(ServiceUtil.getLoginName(request));
        // 用ProjectAddress字段存用户的组织地址
        supervision.setProjectAddress(ServiceUtil.getOrgName(request).replace("地震局", ""));
        supervision.setCreateTime(new Date());
        // 拟制公告状态设置默认值0：未拟制
        supervision.setNoticeStatus("0");
        /**
         * 新增apTodo待办任务
         * 若是暂存，待办事件新增一条暂存待办---------->暂存取消
         * 若是新增提交，待办事件新增一条提交待办
         */
        if ("1".equals(supervision.getCheckStatus()))
            setApTodo(supervision);
        // 新增
        supervisionMapper.save(supervision);
    }

    @Override
    public void update(Supervision supervision) {
        if (supervision == null) {
            throw new RuntimeException("备案表为空");
        }
        if (StringUtils.isEmpty(supervision.getSuId())) {
            throw new RuntimeException("备案表ID为空");
        }
        // 更新创建时间
        supervision.setCreateTime(new Date());
        supervision.setUpdateTime(new Date());
        supervision.setUpdateUser(ServiceUtil.getLoginName(request));
        // 根据ID修改
        supervisionMapper.save(supervision);
    }

    @Transactional
    @Override
    public void check(Supervision supervision) {
        if (supervision == null) {
            throw new RuntimeException("备案表为空");
        }
        if (StringUtils.isEmpty(supervision.getSuId())) {
            throw new RuntimeException("备案表ID为空");
        }
        // 更新创建时间
        supervision.setCreateTime(new Date());
        // 修改审核结果后，同时修改审核状态
        String checkResult = supervision.getCheckResult();
        if (checkResult != null) {
            if ("0".equals(checkResult))
                supervision.setCheckStatus("2");
            else if ("1".equals(checkResult))
                supervision.setCheckStatus("3");
        }
        // 修改apTodo任务状态变成2：已办
        QApTodoEntity q = QApTodoEntity.apTodoEntity;
        jpaQueryFactory.update(q).
                set(q.status, Constant.STATUSYB)
                .where(q.linkId.eq(supervision.getSuId()))
                .execute();
        // 根据ID修改
        supervisionMapper.save(supervision);
    }

    /**
     * 主表和子表逻辑删除
     *
     * @param id
     */
    @Override
    @Transactional
    public void logicDel(String id) {
        if (StringUtils.isEmpty(id)) {
            throw new RuntimeException("ID不能为空");
        }
        // 主表删除标记置为删除
        QSupervision q = QSupervision.supervision;
        jpaQueryFactory.update(q)
                .set(q.delFlag, Constant.DELETE)
                .where(q.suId.eq(id))
                .execute();
        // 子表删除
        supervisionChildService.logicDel(id);
    }

    @Override
    @Transactional
    public void updateReportStatus(String id) {
        if (StringUtils.isEmpty(id)) {
            throw new RuntimeException("ID不能为空");
        }
        QSupervision q = QSupervision.supervision;
        jpaQueryFactory.update(q)
                .set(q.reportStatus, "1")
                .where(q.suId.eq(id))
                .execute();
    }

    /**
     * 更新审核状态为1：已提交待审核
     * 按钮提交不进页面
     *
     * @param id
     */
    @Override
    @Transactional
    public void updateSubmitStatus(String id) {
        if (StringUtils.isEmpty(id)) {
            throw new RuntimeException("ID不能为空");
        }
        QSupervision q = QSupervision.supervision;
        jpaQueryFactory.update(q)
                .set(q.checkStatus, "1")
                .where(q.suId.eq(id))
                .execute();
        // 变为1：已提交待办后，新增一条待办任务
        Supervision supervision = supervisionMapper.findById(id).get();
        setApTodo(supervision);
    }

    @Override
    @Transactional
    public void recallSubmitStatus(String id) {
        if (StringUtils.isEmpty(id)) {
            throw new RuntimeException("ID不能为空");
        }
        QSupervision q = QSupervision.supervision;
        jpaQueryFactory.update(q)
                .set(q.checkStatus, "0")
                .where(q.suId.eq(id))
                .execute();
    }

    /**
     * 开展监管工作
     *
     * @param apPublicEntity
     */
    @Override
    @Transactional
    public void addPublick(ApPublicEntity apPublicEntity) {
        if (apPublicEntity == null || StringUtils.isEmpty(apPublicEntity.getRelationId())) {
            // RelationId关联表id,即一开展监管的ID
            throw new RuntimeException("拟制公告保存失败!");
        }
        /**
         * 添加公告：设置默认值
         */
        if (StringUtils.isEmpty(apPublicEntity.getPublicId())) {
            // 公告主键ID,前端会生成带回，一般不用设置
            apPublicEntity.setPublicId(SnowflakeId.getId());
        }
        apPublicEntity.setRevokeg(Constant.REVOKE_NO);
        apPublicEntity.setDelFlag(Constant.NO_DELETE);
        // 获取用户信息赋值给公告
        apPublicEntity.setCreateUser(ServiceUtil.getLoginName(request));
        apPublicEntity.setOrganName(ServiceUtil.getOrgName(request));
        apPublicEntity.setCreateTime(new Date());
        apPublicEntity.setInputenTime(new Date());
        // 根据此请求路径+RelationId 前端axios获取信息，请求参数Id
        apPublicEntity.setPublicUrl("/dzjap/supervision/getInfo");
        // 设置类型4：开展监管工作，根据此类型前端判断进入哪个页面
        apPublicEntity.setFictionType("4");
        publicDao.save(apPublicEntity);
        /**
         * 拟制公告添加待办已办：调取待办接口
         */
        ApTodoEntity apTodoEntity = new ApTodoEntity();
        apTodoEntity.setStatus(Constant.STATUSDB);
        apTodoEntity.setCreateTime(new Date());
        apTodoEntity.setDelFlag(Constant.NO_DELETE);
        apTodoEntity.setTitle(apPublicEntity.getTitle() + "公开公告审批");
        apTodoEntity.setLinkId(apPublicEntity.getPublicId());
        // 审批员才能看到相应的审批
        apTodoEntity.setStation("地震部门审定人员");
        // 去审批页
        apTodoEntity.setUrl("../todolist/publick.html");
        apTodoEntity.setLocation(apPublicEntity.getOrganName());
        apTodoEntity.setCreatePerson(ServiceUtil.getLoginName(request));
        // 审批的业务
        apTodoEntity.setTypeFlag(Constant.TYPRFLAGSS);
        apTodoMapper.save(apTodoEntity);
        /**
         * 设置拟制公告状态为1：已拟制
         */
        QSupervision q = QSupervision.supervision;
        jpaQueryFactory.update(q)
                .set(q.noticeStatus, "1")
                .where(q.suId.eq(apPublicEntity.getRelationId()), q.delFlag.eq(Constant.NO_DELETE))
                .execute();
    }

    @Override
    public ApPublicEntity viewPublickBySuId(String Id) {
        if (StringUtils.isEmpty(Id)) {
            throw new RuntimeException("SuID不能为空!");
        }
        QApPublicEntity q = QApPublicEntity.apPublicEntity;
        ApPublicEntity apPublicEntity = jpaQueryFactory.selectFrom(q)
                .where(q.relationId.eq(Id), q.delFlag.eq(Constant.NO_DELETE))
                .fetchOne();
        return apPublicEntity;
    }
}
